﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Xml.Serialization;
using UniversalGrid.Annotations;

namespace UniversalGrid
{
    public class GridViewModel : INotifyPropertyChanged
    {
        private string _name = "New Grid";
        
        private int? _width;
        private int? _height;

        private int? _minWidth;
        private int? _maxWidth;
        private int? _minHeight;
        private int? _maxHeight;

        private int? _leftMargin;
        private int? _topMargin;
        private int? _rightMargin;
        private int? _bottomMargin;

        private HorizontalAlignment _horizontalAlignment = HorizontalAlignment.Left;
        private VerticalAlignment _verticalAlignment = VerticalAlignment.Top;

        private RowCalculationType _rowCalculationType;
        private ColumnCalculationType _columnCalculationType;
        private GutterCalculationType _gutterCalculationType;
        
        private int? _columnCount;
        private int? _rowCount;

        private int? _columnWidth = 100;
        private int? _rowHeight = 100;
        private GridUnitType _columnType = GridUnitType.Pixel;
        private GridUnitType _rowType = GridUnitType.Pixel;

        private double _actualHeight;
        private double _actualWidth;

        private int? _gutterWidth;
        private int? _gutterHeight;

        private bool _isStartingWithGutter = false;

        private Color _gutterBackground = Colors.Coral;
        private double _gutterOpacity = 0.2;

        private Color _gridColor = Colors.Red;
        private double _gridOpacity = 1;

        private bool _isBaselineGridVisible = false;
        private int _baselineGridThickness = 1;

        private bool _isFirstLineInCell = false;

        private Color _baselineGridColor = Colors.Blue;
        private double _baselineGridOpacity = 1;

        private int _gridThickness = 1;

        [XmlIgnore]
        private FontFamily _fontFamily = SystemFonts.MessageFontFamily;
        private double? _fontSize = 16;
        private FontWeight _fontWeight = SystemFonts.MessageFontWeight;
        private FontStretch _fontStretch = new FontStretch();
        private FontStyle _fontStyle = SystemFonts.MessageFontStyle;
        private double _lineHeight = 1;
        private int _cellHeight = 1;
 
        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        public string Name
        {
            get { return _name; }
            set
            {
                if (value == _name) return;
                _name = value;
                RaisePropertyChanged("Name");
            }
        }

        public int? Width
        {
            get { return _width; }
            set
            {
                if (value == _width) return;
                _width = value;
                RaisePropertyChanged("Width");
            }
        }

        public int? Height
        {
            get { return _height; }
            set
            {
                if (value == _height) return;
                _height = value;
                RaisePropertyChanged("Height");
            }
        }

        public int? MinWidth
        {
            get { return _minWidth; }
            set
            {
                if (value == _minWidth) return;
                _minWidth = value;
                RaisePropertyChanged("MinWidth");
            }
        }

        public int? MaxWidth
        {
            get { return _maxWidth; }
            set
            {
                if (value == _maxWidth) return;
                _maxWidth = value;
                RaisePropertyChanged("MaxWidth");
            }
        }

        public int? MinHeight
        {
            get { return _minHeight; }
            set
            {
                if (value == _minHeight) return;
                _minHeight = value;
                RaisePropertyChanged("MinHeight");
            }
        }

        public int? MaxHeight
        {
            get { return _maxHeight; }
            set
            {
                if (value == _maxHeight) return;
                _maxHeight = value;
                RaisePropertyChanged("MaxHeight");
            }
        }

        public int? LeftMargin
        {
            get { return _leftMargin; }
            set
            {
                if (value == _leftMargin) return;
                _leftMargin = value;
                RaisePropertyChanged("LeftMargin");
            }
        }

        public int? TopMargin
        {
            get { return _topMargin; }
            set
            {
                if (value == _topMargin) return;
                _topMargin = value;
                RaisePropertyChanged("TopMargin");
            }
        }

        public int? RightMargin
        {
            get { return _rightMargin; }
            set
            {
                if (value == _rightMargin) return;
                _rightMargin = value;
                RaisePropertyChanged("RightMargin");
            }
        }

        public int? BottomMargin
        {
            get { return _bottomMargin; }
            set
            {
                if (value == _bottomMargin) return;
                _bottomMargin = value;
                RaisePropertyChanged("BottomMargin");
            }
        }

        public HorizontalAlignment HorizontalAlignment
        {
            get { return _horizontalAlignment; }
            set
            {
                if (value == _horizontalAlignment) return;
                _horizontalAlignment = value;
                RaisePropertyChanged("HorizontalAlignment");
            }
        }

        public VerticalAlignment VerticalAlignment
        {
            get { return _verticalAlignment; }
            set
            {
                if (value == _verticalAlignment) return;
                _verticalAlignment = value;
                RaisePropertyChanged("VerticalAlignment");
            }
        }

        public RowCalculationType RowCalculationType
        {
            get { return _rowCalculationType; }
            set
            {
                if (Equals(value, _rowCalculationType)) return;
                _rowCalculationType = value;
                RaisePropertyChanged("RowCalculationType");
            }
        }

        public ColumnCalculationType ColumnCalculationType
        {
            get { return _columnCalculationType; }
            set
            {
                if (Equals(value, _columnCalculationType)) return;
                _columnCalculationType = value;
                RaisePropertyChanged("ColumnCalculationType");
            }
        }

        public GutterCalculationType GutterCalculationType
        {
            get { return _gutterCalculationType; }
            set
            {
                if (value == _gutterCalculationType) return;
                _gutterCalculationType = value;
                RaisePropertyChanged("GutterCalculationType");
            }
        }

        public int? ColumnCount
        {
            get { return _columnCount; }
            set
            {
                if (value == _columnCount) return;
                _columnCount = value;
                RaisePropertyChanged("ColumnCount");
            }
        }

        public int? RowCount
        {
            get { return _rowCount; }
            set
            {
                if (value == _rowCount) return;
                _rowCount = value;
                RaisePropertyChanged("RowCount");
            }
        }

        public int? ColumnWidth
        {
            get { return _columnWidth; }
            set
            {
                if (value == _columnWidth) return;
                _columnWidth = value;
                RaisePropertyChanged("ColumnWidth");
            }
        }

        public int? RowHeight
        {
            get { return _rowHeight; }
            set
            {
                if (value == _rowHeight) return;
                _rowHeight = value;
                RaisePropertyChanged("RowHeight");
            }
        }

        public double ActualHeight
        {
            get { return _actualHeight; }
            set
            {
                if (value.Equals(_actualHeight)) return;
                _actualHeight = value;
                RaisePropertyChanged("ActualHeight");
            }
        }

        public GridUnitType ColumnType
        {
            get { return _columnType; }
            set
            {
                if (value == _columnType) return;
                _columnType = value;
                RaisePropertyChanged("ColumnType");
            }
        }

        public GridUnitType RowType
        {
            get { return _rowType; }
            set
            {
                if (value == _rowType) return;
                _rowType = value;
                RaisePropertyChanged("RowType");
            }
        }

        public double ActualWidth
        {
            get { return _actualWidth; }
            set
            {
                if (value.Equals(_actualWidth)) return;
                _actualWidth = value;
                RaisePropertyChanged("ActualWidth");
            }
        }

        public int? GutterWidth
        {
            get { return _gutterWidth; }
            set
            {
                if (value == _gutterWidth) return;
                _gutterWidth = value;
                RaisePropertyChanged("GutterWidth");
            }
        }

        public int? GutterHeight
        {
            get { return _gutterHeight; }
            set
            {
                if (value == _gutterHeight) return;
                _gutterHeight = value;
                RaisePropertyChanged("GutterHeight");
            }
        }

        public Color GutterBackground
        {
            get { return _gutterBackground; }
            set
            {
                if (value.Equals(_gutterBackground)) return;
                _gutterBackground = value;
                RaisePropertyChanged("GutterBackground");
            }
        }

        public double GutterOpacity
        {
            get { return _gutterOpacity; }
            set
            {
                if (value.Equals(_gutterOpacity)) return;
                _gutterOpacity = value;
                RaisePropertyChanged("GutterOpacity");
            }
        }

        public Color GridColor
        {
            get { return _gridColor; }
            set
            {
                if (value.Equals(_gridColor)) return;
                _gridColor = value;
                RaisePropertyChanged("GridColor");
            }
        }

        public double GridOpacity
        {
            get { return _gridOpacity; }
            set
            {
                if (value.Equals(_gridOpacity)) return;
                _gridOpacity = value;
                RaisePropertyChanged("GridOpacity");
            }
        }

        public bool IsBaselineGridVisible
        {
            get { return _isBaselineGridVisible; }
            set
            {
                if (value.Equals(_isBaselineGridVisible)) return;
                _isBaselineGridVisible = value;
                RaisePropertyChanged("IsBaselineGridVisible");
            }
        }

        public bool IsFirstLineInCell
        {
            get { return _isFirstLineInCell; }
            set
            {
                if (value.Equals(_isFirstLineInCell)) return;
                _isFirstLineInCell = value;
                RaisePropertyChanged("IsFirstLineInCell");
            }
        }

        public Color BaselineGridColor
        {
            get { return _baselineGridColor; }
            set
            {
                if (value.Equals(_baselineGridColor)) return;
                _baselineGridColor = value;
                RaisePropertyChanged("BaselineGridColor");
            }
        }

        public double BaselineGridOpacity
        {
            get { return _baselineGridOpacity; }
            set
            {
                if (value.Equals(_baselineGridOpacity)) return;
                _baselineGridOpacity = value;
                RaisePropertyChanged("BaselineGridOpacity");
            }
        }

        public int BaselineGridThickness
        {
            get { return _baselineGridThickness; }
            set
            {
                if (value == _baselineGridThickness) return;
                _baselineGridThickness = value;
                RaisePropertyChanged("BaselineGridThickness");
            }
        }

        public int GridThickness
        {
            get { return _gridThickness; }
            set
            {
                if (value == _gridThickness) return;
                _gridThickness = value;
                RaisePropertyChanged("GridThickness");
            }
        }

        public bool IsStartingWithGutter
        {
            get { return _isStartingWithGutter; }
            set
            {
                if (value.Equals(_isStartingWithGutter)) return;
                _isStartingWithGutter = value;
                RaisePropertyChanged("IsStartingWithGutter");
            }
        }

        [XmlIgnore]
        public FontFamily FontFamily
        {
            get { return _fontFamily; }
            set
            {
                if (Equals(value, _fontFamily)) return;
                _fontFamily = value;
                RaisePropertyChanged("FontFamily");
            }
        }

        public string SerializableFontValue
        {
            get { return new FontFamilyConverter().ConvertToString(_fontFamily); }
            set { FontFamily = (FontFamily)new FontFamilyConverter().ConvertFromString(value); }
        }

        public double? FontSize
        {
            get { return _fontSize; }
            set
            {
                if (value == _fontSize) return;
                _fontSize = value;
                RaisePropertyChanged("FontSize");
            }
        }

        public FontWeight FontWeight
        {
            get { return _fontWeight; }
            set
            {
                if (value.Equals(_fontWeight)) return;
                _fontWeight = value;
                RaisePropertyChanged("FontWeight");
            }
        }

        public FontStretch FontStretch
        {
            get { return _fontStretch; }
            set
            {
                if (value.Equals(_fontStretch)) return;
                _fontStretch = value;
                RaisePropertyChanged("FontStretch");
            }
        }

        public FontStyle FontStyle
        {
            get { return _fontStyle; }
            set
            {
                if (value.Equals(_fontStyle)) return;
                _fontStyle = value;
                RaisePropertyChanged("FontStyle");
            }
        }

        public double LineHeight
        {
            get { return _lineHeight; }
            set
            {
                if (value.Equals(_lineHeight)) return;
                _lineHeight = value;
                RaisePropertyChanged("LineHeight");
            }
        }

        public int CellHeight
        {
            get { return _cellHeight; }
            set
            {
                if (value == _cellHeight) return;
                _cellHeight = value;
                RaisePropertyChanged("CellHeight");
            }
        }
    }
}
